package ar.uade.edu.fain.ad.server.dao.jpa;

import java.util.ArrayList;

import javax.persistence.PersistenceException;

import org.hibernate.HibernateException;
import org.hibernate.Session;

import ar.uade.edu.fain.ad.server.business.Caja;
import ar.uade.edu.fain.ad.server.business.Cajero;
import ar.uade.edu.fain.ad.server.business.CierreCaja;
import ar.uade.edu.fain.ad.server.business.Empleado;
import ar.uade.edu.fain.ad.server.business.Factura;
import ar.uade.edu.fain.ad.server.business.Local;
import ar.uade.edu.fain.ad.server.dao.CajaDAO;
import ar.uade.edu.fain.ad.server.dao.CierreCajaDAO;
import ar.uade.edu.fain.ad.server.dao.entity.CajaEntity;
import ar.uade.edu.fain.ad.server.dao.entity.CierreCajaEntity;
import ar.uade.edu.fain.ad.server.dao.entity.EmpleadoEntity;
import ar.uade.edu.fain.ad.server.dao.entity.FacturaEntity;
import ar.uade.edu.fain.ad.server.dao.entity.LocalEntity;

public class CajaJpaDAO 
		extends GenericJpaDAO<Caja, CajaEntity, Long> 
		implements CajaDAO {

	private CierreCajaDAO cierreCajaDAO;
	
	public CajaJpaDAO() {
		super(CajaEntity.class);
	}

	public CierreCajaDAO getCierreCajaDAO() {
		return cierreCajaDAO;
	}

	public void setCierreCajaDAO(CierreCajaDAO cierreCajaDAO) {
		this.cierreCajaDAO = cierreCajaDAO;
	}

	@Override
	protected CajaEntity toEntity(final Caja business) {
		final Session session = getSession();
		CajaEntity entity;
		if (business.getId() == null) {
			entity = new CajaEntity();
			entity.setCierres(new ArrayList<CierreCajaEntity>());
			entity.setEmpleados(new ArrayList<EmpleadoEntity>());
			entity.setFacturas(new ArrayList<FacturaEntity>());
		} else {
			entity = (CajaEntity) session.get(
					CajaEntity.class, business.getId());
		}
		entity.setId(business.getId());
		entity.setLocal((LocalEntity) session.get(
				LocalEntity.class, business.getLocal().getId()));
		for (Factura factura : business.getFacturas()) {
			final FacturaEntity facturaEntity = (FacturaEntity) 
					session.get(FacturaEntity.class, factura.getId());
			entity.getFacturas().add(facturaEntity);
		}
		for (CierreCaja cierreCaja : business.getCierres()) {
			final CierreCajaEntity cierreCajaEntity = 
					(CierreCajaEntity) session.get(
							CierreCajaEntity.class, cierreCaja.getId());
			entity.getCierres().add(cierreCajaEntity);
		}
		for (Empleado empleado : business.getEmpleados()) {
			final EmpleadoEntity empleadoEntity = 
					(EmpleadoEntity) session.get(
							EmpleadoEntity.class, empleado.getId());
			entity.getEmpleados().add(empleadoEntity);
		}
		return entity;
	}

	@Override
	protected Caja toBusiness(final CajaEntity entity) {
		final Caja business = new Caja();
		business.setId(entity.getId());
		final Local local = new Local();
		local.setId(entity.getLocal().getId());
		business.setLocal(local);
		for (CierreCajaEntity cierreCajaEntity : entity.getCierres()) {
			final CierreCaja cierreCaja = 
					getCierreCajaDAO().get(cierreCajaEntity.getId());
			cierreCaja.setCaja(business);
			business.getCierres().add(cierreCaja);
		}
		for (EmpleadoEntity empleadoEntity : entity.getEmpleados()) {
			final Cajero cajero = new Cajero();
			cajero.setId(empleadoEntity.getId());
			business.getEmpleados().add(cajero);
		}
		for (FacturaEntity facturaEntity : entity.getFacturas()) {
			final Factura factura = new Factura();
			factura.setId(facturaEntity.getId());
			business.getFacturas().add(factura);
		}
		return business;
	}
	
	@Override
	public Caja buscarParaLocal(final Long idLocal) {
		return execute(new Query<Caja>() {
			@Override
			public Caja inTransaction(final Session session)
					throws PersistenceException {
				try {
					final CajaEntity entity = 
							(CajaEntity) session.getNamedQuery("caja.byLocalId")
									.setParameter("localId", idLocal)
									.uniqueResult();
					return toBusiness(entity);
				} catch (HibernateException e) {
					throw new PersistenceException(
							"Inconsistencia en base con la caja del local " +
							"solicitado. Local: " + idLocal + ".");
				}
			}
		});
	}
	
	
}
